import * as crypto from "crypto";

//块类
class Block {
  readonly nonce: number;
  readonly hash: string;

  constructor(
    readonly index: number,
    readonly previousHash: string,
    readonly timestamp: number,
    readonly data: string
  ) {
    const { nonce, hash } = this.myNonce(); //计算nonce和hash
    this.nonce = nonce;
    this.hash = hash;
  }

  private calculateHash(nonce: number): string {
    const data = `${this.index}${this.previousHash}${this.timestamp}${this.data}${nonce}`;  //计算hash
    return crypto.createHash("sha256").update(data).digest("hex");
  }

  private myNonce(): { nonce: number; hash: string } {
    let hash: string;
    let nonce = 0;

    do {
      hash = this.calculateHash(++nonce);   //暴力挖掘nonce
    } while (hash.startsWith("00000") === false);   //hash以00000开头则为有效hash
    return { nonce, hash };
  }
}

/**
 * 以下与bc101.ts相同
 */

//定义一个区块链类
class Blockchain {
    private readonly chain: Block[] = []; //链
  
    //获取最近添加的块引用的getter
    private get latestBlock(): Block {
      return this.chain[this.chain.length - 1];
    }
  
    //构造函数，创建创世区块并添加到链中
    constructor() {
      this.chain.push(new Block(0, "0", Date.now(), "Genesis Block"));
    }
  
    //创建新块实例
    addBlock(data: string): void {
      const block = new Block(
        this.latestBlock.index + 1,
        this.latestBlock.hash,
        Date.now(),
        data
      );
      this.chain.push(block);
    }
  }
  
  //创建三区块的链
  console.log("创建创世区块");
  const blockchain = new Blockchain();
  
  console.log("创建第一区块");
  blockchain.addBlock("Block 1");
  
  console.log("创建第二区块");
  blockchain.addBlock("Block 2");
  
  console.log(JSON.stringify(blockchain, null, 2)); //打印链